﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Threading.Tasks;
using Microsoft.Phone.Controls;

namespace Windows.Security.Authentication.Web
{
    public enum WebAuthenticationOptions
    {
        // Summary:
        //     No options are requested.
        None = 0,
        //
        // Summary:
        //     Tells the web authentication broker to not render any UI. For use with Single
        //     Sign On (SSO). If the server tries to display a webpage, the authentication
        //     operation fails. You should try again without this option.
        SilentMode = 1,
        //
        // Summary:
        //     Tells the web authentication broker to return the window title string of
        //     the webpage in the ResponseData property.
        UseTitle = 2,
    }

    public enum WebAuthenticationStatus
    {
        // Summary: 
        //     The operation succeeded, and the response data is available.
        Success = 0,
        //
        // Summary:
        //     The operation was canceled by the user.
        UserCancel = 1,
        //
        // Summary:
        //     The operation failed because a specific HTTP error was returned, for example
        //     404.
        ErrorHttp = 2,
    }

    public static class WebAuthenticationBrokerSettings
    {

        public static string PageTweaks { get; set; }
    }

    public static class WebAuthenticationBroker
    {

        public async static Task<WebAuthenticationResult> AuthenticateAsync(WebAuthenticationOptions webAuthenticationOptions, Uri StartUri, Uri EndUri = null)
        {
            // Step 1 is to find the UI 
            var rootFrame = (PhoneApplicationFrame)Application.Current.RootVisual;
            var rootPage = (PhoneApplicationPage)rootFrame.Content;
            var layoutRoot = rootPage.Content;

            var webAuthControl = new WebAuthenticationBrokerUI();
            
            Grid newLayoutRoot;
            bool replacedLayoutRoot = false;
            if (layoutRoot is Grid && ((Grid)layoutRoot).ColumnDefinitions.Count <= 1 && ((Grid)layoutRoot).RowDefinitions.Count <= 1)
            {
                // If layoutRoot is a Grid with 1 Column and 1 Row, then we can use it as is
                newLayoutRoot = (Grid)layoutRoot;
            }
            else
            {
                // If root is not a Grid with 1 Column and 1 Row then we create our own grid and replace the current layout root
                newLayoutRoot = new Grid
                {
                    HorizontalAlignment = HorizontalAlignment.Stretch,
                    VerticalAlignment = VerticalAlignment.Stretch
                };
                rootPage.Content = newLayoutRoot;
                newLayoutRoot.Children.Add(layoutRoot);

                replacedLayoutRoot = true;
            }
            newLayoutRoot.Children.Add(webAuthControl);

            webAuthControl.Launch(StartUri, EndUri);

            // For this to be complete, We need to account for the webAuthenticationOptions

            // Step2 Wait for IsComplete to be true
            while (!webAuthControl.IsComplete)
            {
                await TaskEx.Delay(25);
            }

            var result = webAuthControl.Result;

            // CleanUp
            webAuthControl.Visibility = Visibility.Collapsed;

            if (replacedLayoutRoot)
            {
                newLayoutRoot.Children.Remove(webAuthControl);
                newLayoutRoot.Children.Remove(layoutRoot);
                rootPage.Content = layoutRoot;
            }

            return result;
        }
    }

    public class WebAuthenticationResult
    {
        // Summary:
        //     Contains the protocol data when the operation successfully completes.
        //
        // Returns:
        //     The returned data.
        public object ResponseData { get; internal set; }
        //
        // Summary:
        //     Returns the HTTP error code when ResponseStatus is equal to WebAuthenticationStatus.ErrorHttp.
        //     This is only available if there is an error.
        //
        // Returns:
        //     The specific HTTP error, for example 400.
        public uint ResponseErrorDetail { get; internal set; }
        //
        // Summary:
        //     Contains the status of the asynchronous operation when it completes.
        //
        // Returns:
        //     One of the enumerations.
        public WebAuthenticationStatus ResponseStatus { get; internal set; }
    }

    
}
